package cj.web.sc.controllers;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.paoding.rose.web.annotation.Param;
import net.paoding.rose.web.annotation.Path;
import net.paoding.rose.web.annotation.rest.Get;
import net.paoding.rose.web.annotation.rest.Post;
import net.paoding.rose.web.var.Model;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.parser.Parser;
import org.jsoup.parser.XmlTreeBuilder;
import org.springframework.beans.factory.annotation.Autowired;

import cj.utils.Constants;
import cj.utils.ReturnUUID;
import cj.utils.weixin.pay.PayConstants;
import cj.utils.weixin.pay.UnifiedOrder;
import cj.web.BaseController;
import cj.web.marriage.constants.MarriageSCOrderStatusEnum;
import cj.web.sc.dao.GoodsDAO;
import cj.web.sc.dao.OrderDAO;
import cj.web.sc.dao.UserDAO;

@Path("order")
public class OrderController extends BaseController{
	@Autowired
	private GoodsDAO goodsDao;
	@Autowired
	private OrderDAO orderDao;
	@Autowired
	private UserDAO userDao;
	
	@Get("orderConfirm") //确认订单
	public String orderConfirm(Model model, @Param("goodsItemIds")String goodsItemIds, @Param("counts")String counts, @Param("addressId")String addressId,HttpServletRequest request) throws Exception{
		if( isLogin(request) ){
			int buyerId = getBuyerId(request);
			model.add("buyerId", buyerId);
			
			//地址初始化
			if( addressId != null && addressId.length() > 0 ){
				List<Map> address = userDao.getAddressById(addressId);
				if(address != null && address.size() > 0){
					model.add("Address", address.get(0));
				}
			}
			else{
				List<Map> address = userDao.getDefaultAddress(buyerId);
				if(address != null && address.size() > 0){
					model.add("Address", address.get(0));
				}
			}
			
			//商品初始化
			if(goodsItemIds != null && goodsItemIds.length() > 0 && 
					counts != null && counts.length() > 0){
				String[] itemIds = goodsItemIds.split(",");
				String[] itemCnts = counts.split(",");
				List<Map> objs = new ArrayList<Map>();
				if(itemIds != null && itemIds.length > 0 && itemCnts != null && 
						itemCnts.length > 0 && itemIds.length == itemCnts.length){
					for(int i = 0; i < itemIds.length; i++){
						int itemId = Integer.parseInt(itemIds[i]);
						int count = Integer.parseInt(itemCnts[i]);
						List<Map> goodsItem = goodsDao.getGoodsItemById(itemId);
						if(goodsItem != null && goodsItem.size() > 0){
							Map obj = goodsItem.get(0);
							int inventory = Integer.parseInt(obj.get("inventory").toString());  //验证库存
							if(inventory < count){
								String goodsName = obj.get("name").toString();
								model.add("warning", goodsName + "库存不足");
								return "/views/marry/mall/orderNothing.vm";
							}
							obj.put("propValueNames", obj.get("propValueNames").toString().replaceAll(",", ""));
							obj.put("count", itemCnts[i]);
							objs.add(obj);
						}
						else{
							model.add("warning", "该商品已下架");
							return "/views/marry/mall/orderNothing.vm";
						}
					}
				}
				else{
					model.add("warning", "该商品已下架");
					return "/views/marry/mall/orderNothing.vm";
				}
				model.add("Objs",objs);
			
				if(objs.size() > 0){
					int sellerId = Integer.parseInt(objs.get(0).get("sellerId").toString());
					String sellerName = goodsDao.getSellerName(sellerId);
					model.add("sellerId",sellerId);
					model.add("sellerName",sellerName);
				}
			}
			else{
				model.add("warning", "该商品已下架");
				return "/views/marry/mall/orderNothing.vm";
			}
			
			model.add("goodsItemIds",goodsItemIds);
			model.add("counts",counts);
			
			Map<String, String> config = getConfigSign(request);
			model.add("Config",config);
			return "/views/marry/mall/orderConfirm.vm";
		}
		else{
			String retPg = URLEncoder.encode("order/orderConfirm?goodsItemIds=" + goodsItemIds + "&counts=" + counts, "utf-8");
			return "r:../user/login?returnPage=" + retPg;
		}
	}
	
	@Get("cart") //购物车
	public String cart(Model model, HttpServletRequest request){
		if( isLogin(request) ){
			int buyerId = getBuyerId(request);
			List<Map> Objs = orderDao.cartByBuyerId(buyerId);
			if(Objs != null && Objs.size() > 0){
				model.add("Objs", Objs);
			}
			else{
				model.add("warning", "购物车空空如也~");
				return "/views/marry/mall/orderNothing.vm";
			}
			
		}
		else{
			return "r:../user/login?returnPage=order/cart";
		}
		
		return "/views/marry/mall/cart.vm";
	}
	
	@Get("emptyCart")
	public String emptyCart(Model model){
		model.add("warning", "购物车空空如也~");
		return "/views/marry/mall/orderNothing.vm";
	}
	
	@Post("delCart")
	public String delCart(@Param("ids")String ids){
		JSONObject jo = new JSONObject();
		jo.put("returnFlag", Constants.returnObj.returnFlag_true);
		
		JSONArray joIds = JSONArray.fromObject(ids);
		List<Integer> arrIds = new ArrayList<Integer>();
		for(int i = 0; i < joIds.size(); i++){
			arrIds.add(joIds.getInt(i));
		}
		orderDao.delCartByIds(arrIds);
		
		return "@" + jo.toString();
	}
	
	@Post("cartCnt")
	public String cartCnt(HttpServletRequest request){
		JSONObject jo = new JSONObject();
		jo.put("returnFlag", Constants.returnObj.returnFlag_true);
		
		int cartCnt = 0;
		if(isLogin(request)){
			int buyerId = getBuyerId(request);
			cartCnt = orderDao.getCartCntByBuyerId(buyerId);
		}
		
		jo.put("cartCnt", cartCnt);
		return "@" + jo.toString();
	}
	
	@Post("settleAccounts")
	public String settleAccounts(@Param("sellerId")int sellerId, @Param("buyerId")int buyerId, @Param("discntPrice")String discntPrice, 
			@Param("addressId")String addressId, @Param("isInvoice")int isInvoice, @Param("invoiceHead")String invoiceHead,
			@Param("memo")String memo, @Param("goodsItemIds")String goodsItemIds, @Param("counts")String counts, @Param("cartIds")String cartIds,
			HttpServletRequest request) throws Exception{
		JSONObject jo = new JSONObject();
		jo.put("returnFlag", Constants.returnObj.returnFlag_true);
		
		//验证库存
		if(goodsItemIds != null && goodsItemIds.length() > 0 && 
				counts != null && counts.length() > 0){
			String[] itemIds = goodsItemIds.split(",");
			String[] itemCnts = counts.split(",");
			if(itemIds != null && itemIds.length > 0 && itemCnts != null && 
					itemCnts.length > 0 && itemIds.length == itemCnts.length){
				for(int i = 0; i < itemIds.length; i++){
					int goodsItemId = Integer.parseInt(itemIds[i]);
					int count =  Integer.parseInt(itemCnts[i]);
					
					List<Map> goodsItem = goodsDao.getGoodsItemById(goodsItemId);
					if(goodsItem != null && goodsItem.size() > 0){
						Map obj = goodsItem.get(0);
						int inventory = Integer.parseInt(obj.get("inventory").toString());  //验证库存
						if(inventory < count){
							jo.put("goodsName", obj.get("name").toString() + "库存不足");
							jo.put("returnFlag", Constants.returnObj.returnFlag_repeat);
							return "@" + jo.toString();
						}
					}
					else{
						jo.put("goodsName", "该商品已下架");
						jo.put("returnFlag", Constants.returnObj.returnFlag_repeat);
						return "@" + jo.toString();
					}
					
				}
			}
			else{
				jo.put("goodsName", "该商品已下架");
				jo.put("returnFlag", Constants.returnObj.returnFlag_repeat);
				return "@" + jo.toString();
			}
		}
		else{
			jo.put("goodsName", "该商品已下架");
			jo.put("returnFlag", Constants.returnObj.returnFlag_repeat);
			return "@" + jo.toString();
		}
		
		String phone = userDao.getPhoneById(buyerId);
		String receiverName = "";
		String receiverPhone = "";
		String receiverAddress = "";
		List<Map> address = userDao.getAddressById(addressId);
		if(address != null && address.size() > 0){
			receiverName = address.get(0).get("receiverName").toString();
			receiverPhone = address.get(0).get("receiverPhone").toString();
			String province = address.get(0).get("province").toString();
			String city = address.get(0).get("city").toString();
			String area = address.get(0).get("area").toString();
			String addr = address.get(0).get("address").toString();
			
			if( city.indexOf(province) > -1 ){
				receiverAddress = city + area + addr;
			}
			else{
				receiverAddress = province + city + area + addr;
			}
		}
		int status = MarriageSCOrderStatusEnum.prepay.getValue();
		String orderNo = ReturnUUID.getOrderNo("");
		
		int orderId = orderDao.createOrder(buyerId,sellerId,orderNo,discntPrice,receiverName,receiverPhone,receiverAddress,
				isInvoice,invoiceHead,memo,status,phone);
		
		//生成订单详情
		if(goodsItemIds != null && goodsItemIds.length() > 0 && 
				counts != null && counts.length() > 0){
			String[] itemIds = goodsItemIds.split(",");
			String[] itemCnts = counts.split(",");
			if(itemIds != null && itemIds.length > 0 && itemCnts != null && 
					itemCnts.length > 0 && itemIds.length == itemCnts.length){
				for(int i = 0; i < itemIds.length; i++){
					int goodsItemId = Integer.parseInt(itemIds[i]);
					int count =  Integer.parseInt(itemCnts[i]);
					orderDao.createOrderItem(orderId,goodsItemId,count,phone);
				}
			}
		}
		
		//如果是从购物车生成订单，删除购物车
		if( cartIds != null && cartIds.length() > 0 ){
			String[] arrCartIds = cartIds.split(",");
			if( arrCartIds!= null && arrCartIds.length > 0){
				List<Integer> arrIds = new ArrayList<Integer>();
				for(int i = 0; i < arrCartIds.length; i++){
					arrIds.add(Integer.valueOf(arrCartIds[i]));
				}
				orderDao.delCartByIds(arrIds);
			}
		}
		
		//调用微信接口
		String tmpPrice = String.valueOf(Float.parseFloat(discntPrice) * 100);
		String total_fee = tmpPrice.substring(0, tmpPrice.indexOf("."));
		//String total_fee = Integer.valueOf((int)(Float.parseFloat(discntPrice) * 100.0)).toString();
		String spbill_create_ip = request.getRemoteAddr();
		String notify_url = request.getScheme() +"://" + request.getServerName() + "/order/result";
        String openId = getCookieValueByName(request, "openId");
        if(openId != null && openId.length() > 0){
        	UnifiedOrder unifiedOrder = new UnifiedOrder();
    		Map prepay = unifiedOrder.getPrepayId("确认订单-我的专属婚品", orderNo, total_fee, spbill_create_ip, notify_url, openId);
    		jo.put("rtn", prepay);
        }
        else{
        	jo.put("returnFlag", Constants.returnObj.returnFlag_flase);
        }
		
		return "@" + jo.toString();
	}
	
	@Post("pay")
	public String pay(@Param("id")int orderId, HttpServletRequest request) throws Exception{
		JSONObject jo = new JSONObject();
		jo.put("returnFlag", Constants.returnObj.returnFlag_true);
		
		List<Map> orderObj = orderDao.getOrderById(orderId);
		
		if(orderObj != null && orderObj.size() > 0){
			Map obj = orderObj.get(0);
			
			//验证商品 及 库存
			List<Map> orderItems = orderDao.getItemsByOrderId(orderId);
			for(Map orderItem : orderItems){
				String goodsName = orderItem.get("goodsItemName").toString();
				int goodsItemId = Integer.parseInt(orderItem.get("goodsItemId").toString());
				int count = Integer.parseInt(orderItem.get("count").toString());
				
				List<Map> goodsItem = goodsDao.getGoodsItemById(goodsItemId);
				if(goodsItem != null && goodsItem.size() > 0){
					Map goods = goodsItem.get(0);
					int inventory = Integer.parseInt(goods.get("inventory").toString());
					if( inventory < count ){
						jo.put("goodsName", goodsName + "库存不足");
						jo.put("returnFlag", Constants.returnObj.returnFlag_repeat);
						return "@" + jo.toString();
					}
					
					int goodsId = Integer.parseInt(goods.get("goodsId").toString());
					List<Map> goodsObj = goodsDao.getGoodsById(goodsId);
					if(goodsObj == null){
						jo.put("goodsName", goodsName + "已下架");
						jo.put("returnFlag", Constants.returnObj.returnFlag_repeat);
						return "@" + jo.toString();
					}
				}
				else{
					jo.put("goodsName", goodsName + "已下架");
					jo.put("returnFlag", Constants.returnObj.returnFlag_repeat);
					return "@" + jo.toString();
				}
			}
			
			//调用微信接口
			String tmpPrice = String.valueOf(Float.parseFloat(obj.get("discntPrice").toString()) * 100);
			String total_fee = tmpPrice.substring(0, tmpPrice.indexOf("."));
			//String total_fee = String.valueOf((Float.parseFloat(obj.get("discntPrice").toString()) * 100.0));
			String spbill_create_ip = request.getRemoteAddr();
			String notify_url = request.getScheme() +"://" + request.getServerName() + "/order/result";
	        String openId = getCookieValueByName(request, "openId");
	        if(openId != null && openId.length() > 0){
	        	UnifiedOrder unifiedOrder = new UnifiedOrder();
	    		Map prepay = unifiedOrder.getPrepayId("确认订单-我的专属婚品", obj.get("orderNo").toString(), total_fee, spbill_create_ip, notify_url, openId);
	    		jo.put("rtn", prepay);
	    		return "@" + jo.toString();
	        }
	        else{
	        	jo.put("returnFlag", Constants.returnObj.returnFlag_flase);
	        	return "@" + jo.toString();
	        }
		}
		else{
			jo.put("goodsName", "该订单已失效");
			jo.put("returnFlag", Constants.returnObj.returnFlag_repeat);
			return "@" + jo.toString();
		}
		
	}
	
	@Post("result")
	public void result(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		try {
			InputStream inStream = request.getInputStream();
			ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
			byte[] buffer = new byte[1024];
			int len = 0;
			while ((len = inStream.read(buffer)) != -1) {
				outSteam.write(buffer, 0, len);
			}
			outSteam.close();
			inStream.close();
			String resultStr = new String(outSteam.toByteArray(), "utf-8");
			Map<String, String> resultMap = analysisRssHead(resultStr);
			String result_code = resultMap.get("result_code");
			
			if (PayConstants.SUCCESS.equals(result_code)) {
				//微信支付订单号
				String transaction_id = resultMap.get("transaction_id");
				
				//商户订单号
				String out_trade_no = resultMap.get("out_trade_no");
				
				//修改订单状态为已付款，加入微信支付单号
				orderDao.updateStatusByNO(MarriageSCOrderStatusEnum.paid.getValue(), out_trade_no, transaction_id); 
				int orderId = orderDao.getIdByOrderNo(out_trade_no);
				List<Map> items = orderDao.getItemsByOrderId(orderId);
				//修改商品数量
				for(Map item : items){
					int id = Integer.parseInt(item.get("goodsItemId").toString());
					int count = Integer.parseInt(item.get("count").toString());
					orderDao.updateGoodsItemCnt(id, count);
				}
				
				// 通知微信.异步确认成功.必写.不然会一直通知后台.八次之后就认为交易失败了.
				response.getWriter().write(setXML("SUCCESS", "OK"));
			} else {
				response.getWriter().write(setXML("FAIL", "FAIL"));
			}

		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	

	private String setXML(String return_code, String return_msg) {
		return "<xml><return_code><![CDATA[" + return_code
				+ "]]></return_code><return_msg><![CDATA[" + return_msg
				+ "]]></return_msg></xml>";
	}
	
	private int getBuyerId(HttpServletRequest request){
    	String phone = getCookieValueByName(request, "phone");
		int buyerId = userDao.getBuyerId(phone);
		
		return buyerId;
    }
	
	public static void main(String[] args)
	{
//		String tmpPrice = String.valueOf(Float.parseFloat("0.01") * 100);
//		String total_fee = tmpPrice.substring(0, tmpPrice.indexOf("."));
//		System.out.println(total_fee);
		String resultStr="<xml>"
				+ "<appid><![CDATA[wxb8851d53461b983d]]></appid>"
				+ "<bank_type><![CDATA[CFT]]></bank_type>"
				+ "<cash_fee><![CDATA[1]]></cash_fee>"
				+ "<fee_type><![CDATA[CNY]]></fee_type>"
				+ "<is_subscribe><![CDATA[Y]]></is_subscribe>"
				+ "<mch_id><![CDATA[1352398401]]></mch_id>"
				+ "<nonce_str><![CDATA[a27bca5cd93b41c48cda2ed6776ef4c2]]></nonce_str>"
				+ "<openid><![CDATA[okInCwyTfH3UrsMFN7AO1k4v1OqY]]></openid>"
				+ "<out_trade_no><![CDATA[20161010164947790]]></out_trade_no>"
				+ "<result_code><![CDATA[SUCCESS]]></result_code>"
				+ "<return_code><![CDATA[SUCCESS]]></return_code>"
				+ "<sign><![CDATA[BBBC15D28FF9BA16A35E99CA32B3F5B3]]></sign>"
				+ "<time_end><![CDATA[20161010165003]]></time_end>"
				+ "<total_fee>1</total_fee>"
				+ "<trade_type><![CDATA[JSAPI]]></trade_type>"
				+ "<transaction_id><![CDATA[4006892001201610106314199723]]></transaction_id>"
				+ "</xml>";
		
			Map<String, String> resultMap = analysisRssHead(resultStr);
			
	}
	
	public static Map analysisRssHead(String resultStr)
	{
		Document doc = Jsoup.parse(resultStr, "", new Parser(new XmlTreeBuilder()));
		
		Element xml = doc.getElementsByTag("xml").first();
		
		Map rep = new HashMap();
		
		String appid = xml.getElementsByTag("appid").first().text();
		String bank_type = xml.getElementsByTag("bank_type").first().text();
		String cash_fee = xml.getElementsByTag("cash_fee").first().text();
		String fee_type = xml.getElementsByTag("fee_type").first().text();
		String is_subscribe = xml.getElementsByTag("is_subscribe").first().text();
		String mch_id = xml.getElementsByTag("mch_id").first().text();
		String nonce_str = xml.getElementsByTag("nonce_str").first().text();
		String openid = xml.getElementsByTag("openid").first().text();
		String out_trade_no = xml.getElementsByTag("out_trade_no").first().text();
		String result_code = xml.getElementsByTag("result_code").first().text();
		String return_code = xml.getElementsByTag("return_code").first().text();
		String sign = xml.getElementsByTag("sign").first().text();
		String time_end = xml.getElementsByTag("time_end").first().text();
		String total_fee = xml.getElementsByTag("total_fee").first().text();
		String trade_type = xml.getElementsByTag("trade_type").first().text();
		String transaction_id = xml.getElementsByTag("transaction_id").first().text();

		rep.put("appid", appid);
		rep.put("bank_type", bank_type);
		rep.put("cash_fee", cash_fee);
		rep.put("fee_type", fee_type);
		rep.put("is_subscribe", is_subscribe);
		rep.put("mch_id", mch_id);
		rep.put("nonce_str", nonce_str);
		rep.put("openid", openid);
		rep.put("out_trade_no", out_trade_no);
		rep.put("result_code", result_code);
		rep.put("return_code", return_code);
		rep.put("sign", sign);
		rep.put("time_end", time_end);
		rep.put("total_fee", total_fee);
		rep.put("trade_type", trade_type);
		rep.put("transaction_id", transaction_id);
		
		return rep;
	}
}
